# client.py
import asyncio
import json
import websockets
from typing import Optional
from nonebot import get_bot, logger
from pydantic import BaseModel
from datetime import datetime
from nonebot_plugin_apscheduler import scheduler

from .config import Config, config_obj

class WSClient:
    def __init__(self):
        self.ws: Optional[websockets.WebSocketClientProtocol] = None
        self.connected = False
        # self.config = Config.from_yaml()
        self.config = config_obj
        print(f"self.config = {self.config}")
        self.lock = asyncio.Lock()
        
    async def connect(self):
        async with self.lock:
            if self.connected:
                return
            while True:
                try:
                    self.ws = await websockets.connect(
                        self.config.ws_server_url,
                        ping_interval=30,
                        ping_timeout=5
                    )
                    self.connected = True
                    content = f"[qwq_mclistener_client]\n连接到WS: {self.config.ws_server_url}\n\n"
                    content += f"配置项内容:\n{self.config}"
                    logger.success(content)
                    await self.send_notification_message(content)
                    await self.listen()
                    for job in scheduler.get_jobs():
                        if job.id == "reconnected_task":
                            job.remove()   
                    break
                except Exception as e:
                    content = f"[qwq_mclistener_client]\n 连接失败，错误信息：: {e}, 5s后再次尝试..."
                    logger.error(content)
                    await self.send_notification_message(content)
                    self.connected = False
                    await asyncio.sleep(5)

    async def listen(self):
        try:
            async for message in self.ws:
                await self.handle_message(message)
        except websockets.ConnectionClosed:
            content = "[qwq_mslistener]WS连接关闭，重连中..."
            await self.send_notification_message(content)
            logger.warning(content)
            self.connected = False
            # await self.connect()
            asyncio.create_task(self.reconnect_scheduler())
            
    
    async def reconnect_scheduler(self):
        async with self.lock:
            if self.connect:
                return;
            while not self.connected:
                try:
                    await self.connect()
                    break
                except Exception as e:
                    logger.error(f"[qwq_mslistener]重连失败：{e}")
                    await asyncio.sleep(5)
    
    async def handle_message(self, message: str):
        try:
            data = json.loads(message)
            
            if (msg_type := data.get("type")) and (player := data.get("player_name")):
                if not getattr(self.config.group_msg_enabled, msg_type, False):
                    return  # 如果该类型的消息被禁用，则直接返回，不发送
            
                # content = {
                #     "player_join": f"🎉🎉🎉 {player} 进入了神秘小服服！！✨✨✨",
                #     "player_leave": f"😢😢😢 {player} 暂时离开啦~呜——👋👋👋",
                #     "player_msg": f"🔈🔈🔈{player}在神秘小服服说{data.get("content")}"
                # }.get(msg_type)
                # print(f"foo = {self.config.group_msg_enabled.player_join}")
                
                custom_msgs = self.config.group_msg_customization
                content_templates = {
                    "player_join": custom_msgs.player_join,
                    "player_leave": custom_msgs.player_leave,
                    "player_msg": custom_msgs.player_msg
                }
                content = content_templates.get(msg_type, "")

                # 替换占位符
                if content:
                    content = content.replace("%PLAYER%", player)
                    if msg_type == "player_msg":
                        content = content.replace("%CONTENT%", data.get("content", ""))
                    content = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]\n\n" + content

                    await self.send_group_message(content)
                
        except Exception as e:
            logger.error(f"消息处理失败: {e}")
    
    async def send_notification_message(self, content: str):
        """发送通知消息，根据配置决定是发送私信还是群消息"""
        bot = get_bot()
        
        if self.config.enable_private_report:
            # 发送私信给指定用户
            for user_id in self.config.report_users:
                try:
                    logger.info(f"发送私信给用户 {user_id}")
                    await bot.send_private_msg(
                        user_id=user_id,
                        message=content
                    )
                except Exception as e:
                    logger.error(f"发送私信失败，用户ID: {user_id}, 错误: {e}")
        else:
            # 发送群消息（原有逻辑）
            for group_id in self.config.target_groups:
                try:
                    logger.info(f"发送群消息到群 {group_id}")
                    await bot.send_group_msg(
                        group_id=group_id,
                        message=content
                    )
                except Exception as e:
                    logger.error(f"发送群消息失败，群ID: {group_id}, 错误: {e}")

    async def send_group_message(self, content: str):        
            bot = get_bot()

            for group_id in self.config.target_groups:
                try:
                    logger.info(f"group id = {group_id}")
                    await bot.send_group_msg(
                        group_id=group_id,
                        message=content
                    )
                except Exception as e:
                    logger.error(f"Send message failed:e= {e}")
        
            
    async def send_to_server(self, data: dict):
        """发送消息到WebSocket服务器"""
        if self.connected and self.ws:
            try:
                message = json.dumps(data)
                await self.ws.send(message)
                logger.info(f"发送消息到服务器: {data}")
            except Exception as e:
                logger.error(f"发送消息到服务器失败: {e}")
        else:
            logger.warning("WebSocket未连接，无法发送消息")
            
    async def shutdown(self):
        if self.ws and not self.ws.closed:
            await self.ws.close()
            logger.info("WebSocket connection closed gracefully")